home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 46 / Amiga Format CD46 (1999-10-20)(Future Publishing)(GB)[!][issue 1999-12].iso / -in_the_mag- / synth_studies / resgrep03b / source / resgrep.cc < prev    next >
C/C++ Source or Header  |  1999-09-15  |  12KB  |  418 lines

  1. //
  2. // ResGrep -- Programm zum nutzen von Mac-Resourcen auf dem Amiga
  3. //
  4. // 22.03.1992 Andre    geschrieben
  5. //
  6.  
  7. extern "C" {
  8. #include <exec/types.h>
  9. #include <clib/asl_protos.h>
  10. #include <clib/exec_protos.h>
  11. #include <clib/gadtools_protos.h>
  12. #include <clib/intuition_protos.h>
  13. };
  14.  
  15. #include "resources.h"
  16. #include "utils.h"
  17. #include "export.h"
  18.  
  19. struct IntuitionBase *IntuitionBase = NULL;
  20. struct GadToolsBase  *GadToolsBase  = NULL;
  21. struct AslBase         *AslBase        = NULL;
  22. struct IFFParseBase  *IFFParseBase  = NULL;
  23.  
  24. struct Screen         *theScreen     = NULL;
  25. struct Window         *theWindow     = NULL;  // Das Hauptfenster
  26. APTR              VisualInfo    = NULL;
  27. struct Menu         *Menus        = NULL;
  28. struct FileRequester *fr        = NULL;  // Mein FileRequester
  29. struct MsgPort         *up        = NULL;  // Mein UserPort
  30.  
  31. list              FileList;          // Hier stehen alle Files drin
  32. FILE             *globalFile;         // Das aktuelle File
  33. bool              AutoSave = true;         // Ist AutoSave gewählt?
  34.  
  35. extern list         *conversions;         // Die Umwandlungsmethoden
  36.  
  37. // Diese Funktion gibt die FileListe frei.
  38. // Dies MUSS expiziet vor dem Ende des Programms geschehen, da Routinen der
  39. // 'intuition.library' zum schliessen der Fenster verwandt werden.
  40. void freeFileList(void)
  41. {
  42.    node *n;
  43.  
  44.    while( (n=FileList.remhead())!=NULL )
  45.       delete ((ResFile *)n);
  46.    FileList.closedis();
  47.    return;
  48. }
  49.  
  50. // Räumt auf.
  51. // Auch diese Funktion muß expliziet vor Ende des Programms aufgerufen
  52. // werden. (Begründung: siehe oben)
  53. void CleanUp(void)
  54. {
  55.    struct Library *ml;
  56.  
  57.    // Es müssen Expliziet die Fenster geschlossen werden
  58.    // da der Destruktor sonst die Libraries benötigt!
  59.    freeFileList();
  60.    if(fr)         FreeFileRequest(fr);
  61.    if(Menus)      FreeMenus( Menus );
  62.    if(up)         {RemPort(up); DeleteMsgPort(up); }
  63.    if(VisualInfo) FreeVisualInfo( VisualInfo );
  64.    if(theScreen)  UnlockPubScreen( 0l, theScreen );
  65.  
  66.    if(IntuitionBase) {ml=(struct Library *)IntuitionBase; CloseLibrary(ml); }
  67.    if(GadToolsBase)  { ml=(struct Library *)GadToolsBase; CloseLibrary(ml); }
  68.    if(AslBase)  { ml=(struct Library *)AslBase; CloseLibrary(ml); }
  69.    if(IFFParseBase)  { ml=(struct Library *)IFFParseBase; CloseLibrary(ml); }
  70.    return;
  71. }
  72.  
  73. // Das Hauptprogramm
  74. // Hier findet so gut wie alles statt und hier gibt es auch die
  75. // MainEventLoop.
  76. int main(void)
  77. {
  78.    node         *theNode, *n;
  79.    struct IntuiMessage     theIMsg, *imsg;
  80.    int             ret;
  81.    int             portnum=0;       // Der Name und die Numer des
  82.    char          portname[25];       // (ARexx-) Ports.
  83.  
  84.    // Elemente aus GadToolsBox:
  85.    struct TextAttr topaz8 =
  86.    {
  87.       ( STRPTR )"topaz.font", 8, 0x00, 0x01
  88.    };
  89.  
  90.    struct NewMenu NewMenu[] =
  91.    {
  92.       NM_TITLE,(UBYTE *)"Project", 0l, 0, 0, 0l,
  93.       NM_ITEM, (UBYTE *)"Open...", (UBYTE *)"O", 0, 0, 0l,
  94.       NM_ITEM, NM_BARLABEL, 0l, 0, 0l, 0l,
  95.       NM_ITEM, (UBYTE *)"Print", (UBYTE *)"P", NM_ITEMDISABLED, 0, 0l,
  96.       NM_ITEM, NM_BARLABEL, 0l, 0, 0l, 0l,
  97.       NM_ITEM, (UBYTE *)"Hide", 0l, 0, 0, 0l,
  98.       NM_SUB, (UBYTE *)"Window", 0l, 0, 0, 0l,
  99.       NM_SUB, (UBYTE *)"Child Windows", 0l, 0, 0, 0l,
  100.       NM_SUB, (UBYTE *)"All Windows", 0l, 0, 0, 0l,
  101.       NM_ITEM, (UBYTE *)"Reveal", 0l, 0, 0, 0l,
  102.       NM_SUB, (UBYTE *)"Child Windows", 0l, 0, 0, 0l,
  103.       NM_SUB, (UBYTE *)"All Windows", 0l, 0, 0, 0l,
  104.       NM_ITEM, (UBYTE *)"Close", (UBYTE *)"K", 0, 0, 0l,
  105.       NM_ITEM, NM_BARLABEL, 0l, 0, 0l, 0l,
  106.       NM_ITEM, (UBYTE *)"About...", 0l, 0, 0, 0l,
  107.       NM_ITEM, NM_BARLABEL, 0l, 0, 0l, 0l,
  108.       NM_ITEM, (UBYTE *)"Quit ResGrep...", (UBYTE *)"Q", 0, 0, 0l,
  109.       NM_TITLE, (UBYTE *)"Settings", 0l, 0, 0, 0l,
  110.       NM_ITEM, (UBYTE *)"Autosave Settings?", 0l, CHECKIT|CHECKED, 0, 0l,
  111.       NM_ITEM, (UBYTE *)"Create Icons?", 0l,
  112.        NM_ITEMDISABLED|CHECKIT|CHECKED, 0, 0l,
  113.       NM_ITEM, NM_BARLABEL, 0l, 0, 0l, 0l,
  114.       NM_ITEM, (UBYTE *)"Edit Conversions...", (UBYTE *)"E", 0, 0, 0l,
  115.       NM_ITEM, NM_BARLABEL, 0l, 0, 0l, 0l,
  116.       NM_ITEM, (UBYTE *)"Load Settings...", 0l, 0, 0, 0l,
  117.       NM_ITEM, (UBYTE *)"Save Settings", 0l, 0, 0, 0l,
  118.       NM_ITEM, (UBYTE *)"Save Settings As...", 0l, 0, 0, 0l,
  119.       NM_END, 0l, 0l, 0, 0l, 0l
  120.    };
  121.  
  122.    // Öffne die Intuition-library als erste, damit ich dann wenigstens
  123.    // bei den anderen Libraries Fehler anzeigen kann.
  124.    if( (IntuitionBase=(struct IntuitionBase *)
  125.     OpenLibrary((UBYTE *)"intuition.library",37))==NULL )
  126.    {
  127.       // Was soll ich tun?!?
  128.       // printf("Kann IntuitionLibrary nicht öffnen.\n");
  129.       CleanUp();
  130.       return 2;
  131.    }
  132.    if( (GadToolsBase=(struct GadToolsBase *)
  133.     OpenLibrary((UBYTE *)"gadtools.library",37))==NULL )
  134.    {
  135.       ResError("Can't open 'gadtools.library'.");
  136.       CleanUp();
  137.       return 1;
  138.    }
  139.    if( (AslBase=(struct AslBase *)
  140.     OpenLibrary((UBYTE *)"asl.library",37))==NULL )
  141.    {
  142.       ResError("Can't open 'asl.library'.");
  143.       CleanUp();
  144.       return 3;
  145.    }
  146.    if( (IFFParseBase=(struct IFFParseBase *)
  147.     OpenLibrary((UBYTE *)"iffparse.library",37))==NULL )
  148.    {
  149.       ResError("Can't open 'iffparse.library'.");
  150.       CleanUp();
  151.       return 3;
  152.    }
  153.    if( (fr=(struct FileRequester *)AllocFileRequest())== NULL )
  154.    {
  155.       ResError("Can't alloc file requester.");
  156.       CleanUp();
  157.       return 4;
  158.    }
  159.  
  160.    if ( NOT( theScreen = LockPubScreen( (UBYTE *)"Workbench" )))
  161.    {
  162.       ResError("Can't lock the Workbench Screen.");
  163.       CleanUp();
  164.       return 5;
  165.    }
  166.    if ( NOT( VisualInfo = GetVisualInfo( theScreen, TAG_DONE )))
  167.    {
  168.       ResError("Can't get Visualinfo.");
  169.       CleanUp();
  170.       return 6;
  171.    }
  172.    if ( NOT( Menus = CreateMenus( NewMenu, GTMN_FrontPen, 0l, TAG_DONE )))
  173.    {
  174.       CleanUp();
  175.       return 7;
  176.    }
  177.  
  178.    LayoutMenus( Menus, VisualInfo, GTMN_TextAttr, &topaz8, TAG_DONE );
  179.  
  180.    // Da ich jetzt kein 'echtes' MainWindow mehr habe, muß ich mich
  181.    // selbst um solche Dinge wie MessagePorts kümmern.
  182.    if( (up=CreateMsgPort())==NULL )
  183.    {
  184.       ResError("Can't create message port.");
  185.       CleanUp();
  186.       return 8;
  187.    }
  188.  
  189.    // Diese folgende Schleife sucht den ersten Namen (laut AUIG) für einen
  190.    // Message Port für ResGrep.
  191.    do
  192.    {
  193.       // Portnamen herrichten
  194.       portnum++;
  195.       sprintf(portname,"RESGREP.%d",portnum);
  196.       // printf("Name: '%s' Find: %d\n",portname,FindPort((UBYTE*)portname));
  197.       // Und nachsehen, ob er schon existiert.
  198.    } while( FindPort((UBYTE*)portname)!=NULL );
  199.  
  200.    up->mp_Node.ln_Name = portname;
  201.    up->mp_Node.ln_Pri  = 0;
  202.    AddPort(up);
  203.  
  204.    // Die Liste, die zum exportieren der Daten notwendig ist (hier steht
  205.    // drin wie und wohin sie exporttert werden) wird angelegt.
  206.    initexport();
  207.    // Die alten Einstellungen werden geladen.
  208.    loadsettings();
  209.  
  210.    // Das HauptWindow (jetzt das FileWindow) öffnen
  211.    FileList.display(up,Menus,readwrite,"pn",35,7, NewXPos(),NewYPos(),
  212.             "ResGrep - FileList", "ResGrep");
  213.    CoordsUsed();
  214.    theWindow=FileList.getwin();
  215.  
  216.    // Das erste File öffnen (was soll mit einem leeren MainWindow geschehen?)
  217.    {
  218.       ResFile *rf=new ResFile();
  219.  
  220.       if( rf->open()==0 )
  221.       {
  222.      // Das Element einketten (safely!)
  223.      FileList.start_change();
  224.      FileList.addtail(rf);
  225.      FileList.end_change();
  226.       }
  227.       else
  228.      delete rf;
  229.    }
  230.  
  231.    // Und ab hier die sagenumwobene, in der sich alles abspielende
  232.    //       MainEventLoop!
  233.    for(;;) {
  234.  
  235.    Wait( 1UL<<(unsigned long)(up->mp_SigBit) );
  236.    while( (imsg=GT_GetIMsg(up)) != NULL )
  237.    {
  238.       // Message kopieren und sofort orginale sofort zurückschicken.
  239.       theIMsg=*imsg;
  240.       GT_ReplyIMsg(imsg);
  241.       // Zuerst einmal alle Messages abfangen, die nicht an ein
  242.       // Fenster weitergegeben werden sollen. Dazu zählen z.B. alle
  243.       // Menuauswahlen.
  244.       switch( theIMsg.Class )
  245.       {
  246.        case IDCMP_INTUITICKS:
  247.      break;
  248.        case IDCMP_MENUPICK:
  249.      {
  250.         int MenuNumber=theIMsg.Code;
  251.         struct MenuItem *Item;
  252.  
  253.         // Die Menueaufwahl: es wird auch der Fall des mehrfachen
  254.         // auswählens berücksichtigt.
  255.         while( MenuNumber!=MENUNULL )
  256.         {
  257.            Item=ItemAddress(Menus,MenuNumber);
  258.            switch( MENUNUM(MenuNumber) )
  259.            {
  260.         case 0:
  261.           switch( ITEMNUM(MenuNumber) )
  262.           {
  263.            case 0:        // Open...
  264.              {
  265.             ResFile *rf=new ResFile();
  266.  
  267.             if( rf->open()==0 )
  268.             {
  269.                // Das Element einketten (safely!)
  270.                FileList.start_change();
  271.                FileList.addtail(rf);
  272.                FileList.end_change();
  273.                break;
  274.             }
  275.             else
  276.                delete rf;
  277.              }
  278.              break;
  279.                     // 1 - BarLab
  280.            case 2:        // Print
  281.              ResWarning("Print\nNot implemented yet.");
  282.              break;
  283.                     // 3 - BarLab
  284.            case 4:        // Hide
  285.              switch( SUBNUM(MenuNumber) )
  286.              {
  287.               case 0:        // Hide >>    Window
  288.             for(n=FileList.getfirst();
  289.                 n->getsucc();n=n->getsucc())
  290.                ((ResFile *)n)->hidewin(&theIMsg);
  291.             break;
  292.               case 1:        // Hide >>    Child Windows
  293.             {
  294.                struct IntuiMessage *im=&theIMsg;
  295.  
  296.                if( theIMsg.IDCMPWindow==FileList.getwin() )
  297.                   im=NULL;
  298.  
  299.                for(n=FileList.getfirst();
  300.                    n->getsucc();n=n->getsucc())
  301.                   ((ResFile *)n)->hidechild(im);
  302.             }
  303.             break;
  304.               case 2:        // Hide >>    All Windows
  305.             for(n=FileList.getfirst();n->getsucc();
  306.                 n=n->getsucc())
  307.                ((ResFile *)n)->hidechild(NULL);
  308.             break;
  309.              }
  310.              break;
  311.            case 5:        // Reveal
  312.              switch( SUBNUM(MenuNumber) )
  313.              {
  314.               case 0:        // Reveal >>  Child Windows
  315.             for(n=FileList.getfirst();
  316.                 n->getsucc();n=n->getsucc())
  317.                ((ResFile *)n)->revealchild(&theIMsg);
  318.             break;
  319.               case 1:        // Reveal >>  All Windows
  320.             for(n=FileList.getfirst();
  321.                 n->getsucc();n=n->getsucc())
  322.                ((ResFile *)n)->revealchild(NULL);
  323.             break;
  324.              }
  325.              break;
  326.            case 6:        // Close
  327.              for(n=FileList.getfirst(); n->getsucc(); n=n->getsucc())
  328.             ((ResFile *)n)->closewin(&theIMsg);
  329.              break;
  330.                     // 7 - BarLab
  331.            case 8:        // About...
  332.              ResMessage("ResGrep\n"
  333.                 "Version 0.3 beta\n"
  334.                 "copyright 1992 by Andreas Florath");
  335.              break;
  336.                     // 9 - BarLab
  337.            case 10:        // Quit...
  338.              CleanUp();
  339.              return 0;
  340.              break;
  341.            default:
  342.              ResError("Fatal:\nUnknown menu item.");
  343.              break;
  344.           }
  345.           break;
  346.         case 1:
  347.           switch( ITEMNUM(MenuNumber) )
  348.           {
  349.            case 0:
  350.              AutoSave = AutoSave ? false : true;
  351.              break;
  352.            case 3:
  353.              editconv();
  354.              if( AutoSave )
  355.             savesettings();
  356.              break;
  357.            case 5:
  358.              loadsettings();
  359.              break;
  360.            case 6:
  361.              savesettings();
  362.              break;
  363.            case 7:
  364.              savesettingsas();
  365.              break;
  366.            default:
  367.              ResError("Fatal:\nUnknown menu item");
  368.              break;
  369.           }
  370.           break;
  371.         default:
  372.           ResError("Fatal:\nUnknown menu");
  373.           break;
  374.            }
  375.            MenuNumber=Item->NextSelect;
  376.         } // End: while( MenuNumber!=MENUNULL ) ...
  377.      } // End: case IDCMP_MENUPICK
  378.      break;
  379.        default: // In allen anderen Fällen wurde ein Fenster angeklickt
  380.      {
  381.         node *theNode;
  382.  
  383.         // Ist es für das MainWindow?
  384.         if( theIMsg.IDCMPWindow==FileList.getwin() )
  385.         {
  386.            switch(theIMsg.Class)
  387.            {
  388.         case IDCMP_CLOSEWINDOW:
  389.           theIMsg.IDCMPWindow=NULL;
  390.           CleanUp();
  391.           return 0;
  392.            }
  393.         }
  394.         theNode=FileList.checkdis(&theIMsg);
  395.         if( theIMsg.IDCMPWindow==NULL )
  396.         {
  397.            if( theNode==NULL )
  398.           break;
  399.            ((ResFile *)theNode)->displaywin(up,Menus);
  400.            break;
  401.         }
  402.         // War ein anderes Fenster gemeint?
  403.         for(node *n=FileList.getfirst(); n->getsucc(); n=n->getsucc())
  404.         {
  405.            globalFile= ((ResFile *)n)->getfp();
  406.            theNode = ((ResFile *)n)->check(&theIMsg);
  407.         }
  408.      }
  409.        break;
  410.       }
  411.    } // End: while( GetIMsg()!=NULL ) ...
  412.  
  413.    } // ForEver - Never
  414.    CleanUp(); // Im Falle eines Falles...
  415.    return 0;
  416. }
  417.  
  418.